package com.example.figurehecheng.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.example.figurehecheng.common.config.checkObjAllFieldsIsNull;
import com.example.figurehecheng.common.constant.MessageConstant;
import com.example.figurehecheng.common.context.BaseContext;
import com.example.figurehecheng.common.exception.AccountExist;
import com.example.figurehecheng.common.properties.JwtProperties;
import com.example.figurehecheng.common.properties.SampleUtils;
import com.example.figurehecheng.common.utils.JwtUtil;
import com.example.figurehecheng.domain.dto.MerchantPasswordDTO;
import com.example.figurehecheng.domain.entity.Merchant;
import com.example.figurehecheng.domain.dto.MerchantRegisterDTO;
import com.example.figurehecheng.mapper.MerchantMapper;
import com.example.figurehecheng.service.IMerchantService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 宇科工作室
 * @since 2024-10-18
 */
@Service
@RequiredArgsConstructor
public class MerchantServiceImpl extends ServiceImpl<MerchantMapper, Merchant> implements IMerchantService {
    private final StringRedisTemplate redisTemplate;

    private final SampleUtils sampleUtils;

    private final JwtProperties jwtProperties;

    /**
     * 商户注册
     * @param merchant
     */
    @Override
    public void register(MerchantRegisterDTO merchant) {
        if (!StrUtil.isAllNotEmpty(merchant.getPhone(),merchant.getPassword(),merchant.getCode(),merchant.getRole())){
        throw new AccountExist(MessageConstant.CODE_NOT_NULL);
    }
    //手机号是否合法
    if (!Pattern.matches("^1[3-9]\\d{9}$", merchant.getPhone())){
        throw new AccountExist(MessageConstant.PHONE_ERR);
    }
        //对密码进行MD5加密
        merchant.setPassword(DigestUtils.md5DigestAsHex((merchant.getPassword()).getBytes()));
        //进行对象拷贝
        Merchant merchant1 = BeanUtil.copyProperties(merchant, Merchant.class);

        //查看是否已经注册
        Merchant merchantOne = lambdaQuery()
                .eq(Merchant::getPhone, merchant1.getPhone())
                .one();
        if (ObjectUtil.isNotNull(merchantOne)){
            throw  new AccountExist(MessageConstant.ACCOUNT_EXIT);
        }
       //查看验证码是否相同
        String code= redisTemplate.opsForValue().get(merchant.getPhone());
        if (ObjectUtil.notEqual(code,merchant.getCode())){
            throw new AccountExist(MessageConstant.CODE_ERROR);
        }
        //新增商户
        save(merchant1);
    }

    /**
     * 通过电话号码获取验证码
     * @param phone
     */
    @Override
    public void code(String phone)  {
        //判断手机号是否合法
        if (ObjectUtil.isNull(phone) || !Pattern.matches("^1[3-9]\\d{9}$", phone)){
            throw new AccountExist(MessageConstant.PHONE_ERR);
        }
        //产生一个长度为6位的验证码
        String codes = RandomUtil.randomNumbers(6);
        redisTemplate.opsForValue().set(phone,codes,5, TimeUnit.MINUTES);
        try {
            sampleUtils.code(phone,codes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 商户登录
     * @param merchant
     */
    @Override
    public String login(MerchantRegisterDTO merchant) {
        Merchant merchant1 = BeanUtil.copyProperties(merchant, Merchant.class);
        Merchant merchant2 = lambdaQuery()
                .eq(Merchant::getPhone, merchant1.getPhone())
                .one();
        //判断商户是否存在
        if (ObjectUtil.isNull(merchant2)){
            throw new AccountExist(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        //查看密码是否正确
        String password = DigestUtils.md5DigestAsHex(merchant.getPassword().getBytes());
        if (!ObjectUtil.equal(password,merchant2.getPassword())){
            throw new AccountExist(MessageConstant.PASSWORD_ERROR);
        }
        HashMap<String, Object> claims = new HashMap<>();
        claims.put("id",merchant2.getId());
        claims.put("phone",merchant2.getPhone());
        claims.put("role",merchant2.getRole());
        String jwt = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(), jwtProperties.getAdminTtl(), claims);
        return jwt;

    }

    /**
     * 忘记密码
     * @param merchantPasswordDTO
     */
    @Override
    public void updatePassword(MerchantPasswordDTO merchantPasswordDTO) {
        //判断是否全部填写
        if (checkObjAllFieldsIsNull.objCheckIsNull(merchantPasswordDTO)){
            throw new AccountExist(MessageConstant.COUPON_NOT_NULL);
        }
        //判断手机号是否合法
        if (ObjectUtil.isNull(merchantPasswordDTO.getPhone()) && !Pattern.matches("^1[3-9]\\d{9}$", merchantPasswordDTO.getPhone())){
            throw new AccountExist(MessageConstant.PHONE_ERR);
        }
        //比对两次密码是否一致
        if (!ObjectUtil.equal(merchantPasswordDTO.getPassword(),merchantPasswordDTO.getPasswords())){
            throw new AccountExist(MessageConstant.PASSWORD_ERRORS);
        }
        Merchant merchant = BeanUtil.copyProperties(merchantPasswordDTO, Merchant.class);
        //判断用户是否存在
        Merchant merchants = lambdaQuery()
                .eq(Merchant::getPhone, merchant.getPhone())
                .one();
        if (ObjectUtil.isNull(merchants)){
            throw new AccountExist(MessageConstant.ACCOUNT_NOT_FOUND);
        }
         //查看验证码是否相同
        String code= redisTemplate.opsForValue().get(merchantPasswordDTO.getPhone());
        if (ObjectUtil.notEqual(code,merchantPasswordDTO.getCode())){
            throw new AccountExist(MessageConstant.CODE_ERROR);
        }

        //修改密码
        lambdaUpdate().set(Merchant::getPassword, DigestUtils.md5DigestAsHex(merchant.getPassword().getBytes()))
                .eq(Merchant::getPhone,merchant.getPhone())
                .eq(Merchant::getId, BaseContext.getCurrentId())
                .update();
    }
}
